-module(irc_bot).
-compile(export_all).

-define(NICKNAME, "SkintBot").
-define(CHANNEL, "#BotErTest").

%% --------------------------------------------------------------
%% @spec connect(Host, Port)
%% --------------------------------------------------------------
connect(Host, Port) ->
    {ok, Sock} = gen_tcp:connect(Host, Port, [{packet, line}]),
    % According to RFC1459, we need to tell the server our nickname and username
    gen_tcp:send(Sock, "NICK " ++ ?NICKNAME ++  "\r\n"),
    gen_tcp:send(Sock, "USER " ++ ?NICKNAME ++  " * * :New Now Know How\r\n"),
    loop(Sock).

%% --------------------------------------------------------------
%% @spec loop(Socket)
%% @doc Now that we're connected, receive TCP messages and parse them.
%% --------------------------------------------------------------
loop(Socket) ->
    receive
        {tcp, Socket, Data} ->
            io:format("[~w] Received: ~s", [Socket, Data]),
            message_filter(Socket, string:tokens(Data, "#")),
            loop(Socket);
        quit ->
            io:format("[~w] Received quit message, exiting...~n", [Socket]),
            gen_tcp:close(Socket),
            exit(stopped)
    end.
    
%% --------------------------------------------------------------
%% @spec handle(message)
%% @doc Parses the data and joins the channel when appropriate
%% Also send the ping response
%% --------------------------------------------------------------
message_filter(Socket, [_Info, Data]) ->
    io:fwrite("Processing: ~s~n", [Data]),
    handle_query(Socket, string:tokens(Data, ":"));
message_filter(Socket, [Info]) ->
    StrIndex = string:str(Info, "376 " ++ ?NICKNAME),
    io:fwrite("~s~n", [Info]),
    if
        StrIndex > 0 ->
            join_channel(Socket);
        true ->
            true
    end;    
message_filter(Socket, ["PING"|Rest]) ->
    gen_tcp:send(Socket, "PONG " ++ Rest ++ "\r\n");
message_filter(_, _) ->
    0.

%% --------------------------------------------------------------
%% @spec handle_query()
%% @doc handle specific queries and pass then to event handler for 
%% further processing
%% --------------------------------------------------------------
handle_query(Socket, [_Username, Query]) ->
    Pid = spawn(fun() -> process() end),
    Pid ! {Socket, string:tokens(Query, " ")};
handle_query(_,_) ->
    ok.
    
%% --------------------------------------------------------------
%% @spec process()
%% @doc
%% --------------------------------------------------------------
process() ->
    receive
        {_Socket, ["youtube"|_Parameters]} ->
            io:fwrite(">>>>>>Youtube~n");
        Any ->
            io:fwrite(">>>>>>Unknown command~p~n", [Any])
    end,
    process().

%% --------------------------------------------------------------
%% @spec join_channel(Socket)
%% --------------------------------------------------------------
join_channel(Socket) ->
    io:fwrite("Joining Channel: ~s~n", [?CHANNEL]),
    gen_tcp:send(Socket, "JOIN :" ++ ?CHANNEL ++ "\r\n").

%% --------------------------------------------------------------
%% @spec irc_channelmsg/2, irc_privmsg/3
%% @doc utility functions to send a response back to channel or a user
%% --------------------------------------------------------------
irc_channelmsg(Socket, Reply) ->
    irc_privmsg(Socket, ?CHANNEL, Reply).

irc_privmsg(Sock, To, Message) ->
    gen_tcp:send(Sock, "PRIVMSG " ++ To ++ " :" ++ Message ++ "\r\n").